/*
new Promise((resolve,reject)=>{
    console.log("开始啦")
    resolve(1)
}).then(value=>{
    console.log('value'+value)
})

可以优化一下代码
*/
 class Promise{
     constructor(exector){
         //不能相信用户的输入 写一个类必须首先要验证用户的输入条件
         //参数校验
        if(typeof exector !== 'function'){
            throw new TypeError(`promise resolve ${exector} is not a function`)
        }
        // 初始化一些状态
        // this.value = null //成功的值
        // this.reason = null //拒因
        // this.state = 'pending'  //状态  
        this.initValue()

        this.initBind()
        //const resolve = function(value){ //这样会导致this指向报错,需要换成箭头函数
        // const resolve = (value) =>{
        //     //成功后的一系列操作（状态的改变，成功回调的执行）
        //     //value 成功的值
        //     if(this.state === 'pending'){
        //         this.state = 'fulfilled'
        //         this.value = value
        //     }
        // }


        // const reject = (reason) =>{
        //     //失败后的一系列操作（状态的改变，失败回调的执行）
        //     //reason 失败的拒因
        //     if(this.state === 'pending'){
        //         this.state = 'rejected'
        //         this.reason = reason
        //     }
            
        // }
    
        exector(this.resolve,this.reject)
     }
     //绑定 this
     initBind(){
         this.resolve = this.resolve.bind(this)
         this.reject = this.reject.bind(this)
     }



     //初始化一些状态
     initValue () {
        this.value = null //成功的值
        this.reason = null //拒因
        this.state = Promise.PENDING  //状态  

        this.onFulfilledCallbacks = [] //成功回调
        this.onRejectedCallbacks = [] //失败的回调
     }

     resolve(value){
        if(this.state === Promise.PENDING){
            this.state = Promise.FULFILED
            this.value = value
            this.onFulfilledCallbacks.forEach((fn) => fn(this.value))
        }
     }

     reject(reason){
        if(this.state === Promise.PENDING){
            this.state = Promise.REJECTED
            this.reason = reason
            this.onRejectedCallbacks.forEach((fn) => fn(this.reason))
        }
     }

     then(onFulfilled,onRejected) {
        //实现链式调用，且改变了后边的then的值，必须通过新的实例

        //参数校验
         if(typeof onFulfilled !== 'function'){
            onFulfilled = function(value){
                return value
            }
         }

         //参数校验
         if(typeof onRejected !== 'function'){
            onRejected = function(reason){
                throw reason
            }
        }
        let promise2 = new Promise((resolve,reject)=>{

            if(this.state === Promise.FULFILED){ //魔法字符串，要避免使用这些魔法字符串
                setTimeout(()=>{
                    try{
                        let x = onFulfilled(this.value)
                        resolve(x)
                    }catch(e){
                        reject(e)
                    }
                })
            }

            if(this.state === Promise.REJECTED){
                setTimeout(()=>{
                    try{
                        let x = onRejected(this.reason)
                        resolve(x)
                    }catch(e){
                        reject(e)
                    }
                 
                })
                
            }

            //追加判断pending
            if(this.state === Promise.PENDING){
                this.onFulfilledCallbacks.push(value =>{
                    setTimeout(()=>{

                        
                        try{
                            let x =  onFulfilled(value)
                            resolve(x)
                        }catch(e){
                            reject(e)
                        }
                    })
                }) 
                this.onRejectedCallbacks.push(reason =>{
                    setTimeout(()=>{
                        try{
                            let x =  onRejected(reason)
                            resolve(x)
                        }catch(e){
                            reject(e)
                        }
                        
                    })
                })
            }
        })
        return promise2

        // //参数校验
        //  if(typeof onFulfilled !== 'function'){
        //     onFulfilled = function(value){
        //         return value
        //     }
        //  }

        //  //参数校验
        //  if(typeof onRejected !== 'function'){
        //     onRejected = function(reason){
        //         throw reason
        //     }
        // }

        // if(this.state === Promise.FULFILED){ //魔法字符串，要避免使用这些魔法字符串
        //     setTimeout(()=>{
        //         onFulfilled(this.value)
        //     })
        // }

        // if(this.state === Promise.REJECTED){
        //     setTimeout(()=>{
        //         onRejected(this.reason)
        //     })
            
        // }

        // //追加判断pending
        // if(this.state === Promise.PENDING){
        //     this.onFulfilledCallbacks.push(value =>{
        //         setTimeout(()=>{
        //             onFulfilled(value)
        //         })
        //     }) 
        //     this.onRejectedCallbacks.push(reason =>{
        //         setTimeout(()=>{
        //             onRejected(reason)
        //         })
        //     })
        // }

     }
 }
 Promise.race = function(promises){
    return new Promise((resolve,reject)=>{
        for(let i=0;i<promises.length;i++){
            promises[i].then(resolve,reject)
        }
    })
 }

 Promise.all = function(promises){
     let arr = []
     let i = 0;
     function processData(index,data){
         arr[index] = data
         i++;
         if(i == promises.length){
             resolve(arr)
         }
     }
     return new Promise((resolve,reject)=>{
        for(let i=0;i<promises.length;i++){
            promises[i].then(data=>{
                processData(i,data)
            },reject)
        }
     })
 }


 Promise.PENDING = 'pending'
 Promise.FULFILED = 'fulfilled'
 Promise.REJECTED = 'rejected'
 Promise.resolvePromise = function(promise2,x,resolve,reject){
    //
    if(promise2 === x){
        reject(new TypeError('Chaining cycle detected for promise'))
    }
    let called = false
    const then = x.then
    if(x instanceof Promise){
        //判断x是否为promise
        then(value =>{
           // resolve(value)
           Promise.resolvePromise(promise2,value,resolve,reject)
        },reason=>{
            reject(reason)
        })

    }else if(x !== null && (typeof x === 'object' || typeof x === 'function')){
        //x为对象的时候
        try{
            
            if(typeof then === 'function'){
                then.call(x,value=>{
                    if(called){
                        return 
                    }
                    called = true
                    Promise.resolvePromise(promise2,value,resolve,reject)
                },reason =>{
                    if(called){
                        return 
                    }
                    called = true
                    reject(reason)
                }) 
            }else{
                if(called){
                    return 
                }
                called = true
                resolve(x)
            }
        }catch(e){
            reject(e)
        }
        
    }else {
        resolve(x)
    }

 }
 Promise.defer = Promise.deferred = function(){
     let dfd = {}
     dfd.promise = new Promise((resolve,reject) =>{
         dfd.resolve = resolve
         dfd.reject = reject
     })
     return dfd
 }
 module.exports = Promise